Hero = Hero or class({}, nil, UnitEntity)

function Hero:constructor(hero)
	getbase(Hero).constructor(self)

	if hero then
		self:SetUnit(hero)
	end

	self.removeOnDeath = false
end

function Hero:SetEquipments()
	if self.equipments == nil then
		self.equipments = Equipments(self)
		self:SetNetTable("equipments", self.equipments:GetIndex())
	end
end

function Hero:GetEquipments()
	return self.equipments
end

function Hero:SetInventory(row, colm)
	if self.inventory == nil then
		self.inventory = ItemContainer(self, row, colm)
		self:SetNetTable("inventory", self.inventory:GetIndex())
	else
		self.inventory:SetRow(row)
		self.inventory:SetColm(colm)
	end
end

function Hero:GetInventory()
	return self.inventory
end

function Hero:SetBackpack(row, colm)
	if self.backpack == nil then
		self.backpack = ItemContainer(self, row, colm)
		self:SetNetTable("backpack", self.backpack:GetIndex())
	else
		self.backpack:SetRow(row)
		self.backpack:SetColm(colm)
	end
end

function Hero:GetBackpack()
	return self.backpack
end

function Hero:AddItem(item)
	if item:IsStackable() then
		local remain = self.equipments:AddItemCharges(item)
		if remain > 0 then
			remain = self.inventory:AddItemCharges(item)
			if remain > 0 then
				remain = self.backpack:AddItemCharges(item)
				if remain > 0 then
					if not self.equipments:AddItemToEmptySlot(item) then
						if not self.inventory:AddItemToEmptySlot(item) then
							if not self.backpack:AddItemToEmptySlot(item) then
								return false
							end
						end
					end
				end
			end
		end
	else
		if not self.equipments:AddItemToEmptySlot(item) then
			if not self.inventory:AddItemToEmptySlot(item) then
				if not self.backpack:AddItemToEmptySlot(item) then
					return false
				end
			end
		end
	end

	return true
end

function Hero:SetUnit(unit)
	getbase(Hero).SetUnit(self, unit)

	unit.hero = self
end

getbase(Hero).IsHero = function(self)
	return false
end
function Hero:IsHero()
	return true
end

function Hero:Animate(gesture, rate)
	if not self:IsValid() then
		return
	end

	if rate ~= nil then
		self:GetUnit():StartGestureWithPlaybackRate(gesture, rate)
	else
		self:GetUnit():StartGesture(gesture)
	end
end

function Hero:Heal(amount, source)
	getbase(Hero).SetUnit(self, amount, source)

	if not self:IsValid() then
		return
	end

	if amount == nil then
		return
	end

	if math.floor(amount) > 0 then
		local sign = ParticleManager:CreateParticle("particles/msg_fx/msg_heal.vpcf", PATTACH_OVERHEAD_FOLLOW, self:GetUnit())
		ParticleManager:SetParticleControl(sign, 1, Vector(10, math.floor(amount), 0))
		ParticleManager:SetParticleControl(sign, 2, Vector(2, 2, 0))
		ParticleManager:SetParticleControl(sign, 3, Vector(100, 255, 50))
		ParticleManager:ReleaseParticleIndex(sign)
	end
end

function Hero:Remove()
	self.inventory:Remove()
	self.backpack:Remove()
	self.equipment:Remove()

	getbase(Hero).Remove(self)
end